/**
 * Created by meiguizhinian on 2018/6/27
 * Copyright © 2018 lixiaolong. All rights reserved.
 */

//TODO：等待完成
ivy.UIListView = ivy.UIBase.extend({
	_className:"ivy.UIListView",
	ctor : function (formName, blockName, sourceControlData) {
		this._super();
		this._layoutChildsVec = [];
		this._lazyLoadVec = new LLArray();
		if (formName && blockName && sourceControlData) {
			this.initWith(formName, blockName, sourceControlData);
		}
	},

	initWith : function(formName, blockName, sourceControlData) {
		this.init();
		let uim = ivy.UIManager.getInstance();
		let x = uim.getBlockDataByType(formName, blockName, ivy.UIManager.FormDataType.ePosX);
		let y = uim.getBlockDataByType(formName, blockName, ivy.UIManager.FormDataType.ePosY);
		let w = uim.getBlockDataByType(formName, blockName, ivy.UIManager.FormDataType.eWidth);
		let h = uim.getBlockDataByType(formName, blockName, ivy.UIManager.FormDataType.eHeight);
		let layerID = uim.getBlockDataByType(formName, blockName, ivy.UIManager.FormDataType.eLayerID);
		this._layerIDInEditor = layerID;

		this.setLocalZOrder(layerID);
		this.setSrcRect(cc.rect(x, y, w, h));
		this.setPosition(ivy.Tools.ConvertPointToGL(cc.p(x + w / 2.0, y + h / 2.0)));
		this.setSrcPosition(this.getPosition());
		this.setContentSize(cc.size(w, h));
		let anchorType = uim.getControlIntDataByFindIndex(sourceControlData.propertyDataFindIndex[ivy.DefaultSourceControlTypes.SCT_ELEMENT_AniBox_Anchor_list]);

		this._enterActionID.setValue(uim.getControlActionDataByFindIndex(sourceControlData.propertyDataFindIndex[ivy.DefaultSourceControlTypes.SCT_ELEMENT_AniBox_EnterAction_action]));
		this._outActionID.setValue(uim.getControlActionDataByFindIndex(sourceControlData.propertyDataFindIndex[ivy.DefaultSourceControlTypes.SCT_ELEMENT_AniBox_OutAction_action]));
		//////////////////////////////////////////////////////////////////////////
		this._listView = new ccui.ListView();
		this._listView.setClippingType(ccui.Layout.CLIPPING_SCISSOR);
		if (this._listView) {
			this._listView.setCascadeColorEnabled(true);
			this._listView.setCascadeOpacityEnabled(true);
			this._listView.setMagneticAllowedOutOfBoundary(false);
			let direction = uim.getControlListDataByFindIndex(sourceControlData.propertyDataFindIndex[ivy.DefaultSourceControlTypes.SCT_ELEMENT_ListView_Direction_list]);
			this._listView.setDirection(direction);
			let bounceEnable= uim.getControlListDataByFindIndex(sourceControlData.propertyDataFindIndex[ivy.DefaultSourceControlTypes.SCT_ELEMENT_ListView_BounceEnable_list]);
			this._listView.setBounceEnabled(bounceEnable===1);
			let gravity= uim.getControlListDataByFindIndex(sourceControlData.propertyDataFindIndex[ivy.DefaultSourceControlTypes.SCT_ELEMENT_ListView_Gravity_list]);
			this._listView.setGravity(gravity);
			let itemsMargin= uim.getControlFloatDataByFindIndex(sourceControlData.propertyDataFindIndex[ivy.DefaultSourceControlTypes.SCT_ELEMENT_ListView_ItemMargin_float]);
			this._listView.setItemsMargin(itemsMargin);
			let inertiaScroll= uim.getControlListDataByFindIndex(sourceControlData.propertyDataFindIndex[ivy.DefaultSourceControlTypes.SCT_ELEMENT_ListView_InertiaScroll_list]);
			this._listView.setInertiaScrollEnabled(inertiaScroll===1);
			let magneticType= uim.getControlListDataByFindIndex(sourceControlData.propertyDataFindIndex[ivy.DefaultSourceControlTypes.SCT_ELEMENT_ListView_MagneticType_list]);
			this._listView.setMagneticType(magneticType);
			let showScrollBar= uim.getControlListDataByFindIndex(sourceControlData.propertyDataFindIndex[ivy.DefaultSourceControlTypes.SCT_ELEMENT_ListView_ScrollBarShowEnable_list]);
			this._listView.setScrollBarEnabled(showScrollBar===1);
			this._listView.setTouchEnabled(true);
			this._listView.setContentSize(cc.size(w, h));
			if (showScrollBar) {
				let scrollBarOffsetX= uim.getControlListDataByFindIndex(sourceControlData.propertyDataFindIndex[ivy.DefaultSourceControlTypes.SCT_ELEMENT_ListView_ScrollBarOffsetX_float]);
				let scrollBarOffsetY = uim.getControlListDataByFindIndex(sourceControlData.propertyDataFindIndex[ivy.DefaultSourceControlTypes.SCT_ELEMENT_ListView_ScrollBarOffsetY_float]);
				this._listView.setScrollBarPositionFromCorner(cc.p(scrollBarOffsetX,scrollBarOffsetY));
			}
			this.addChild(this._listView);
			let pauseScrollFunc = function(){
				if (this._listView) {
					this._listView.setEnabled(false);
				}
			}.bind(this);
			ivy.UIManager.getInstance().registerUIRefreshFunctionWithName(ivy.UIListView.UIListViewPauseScrollEventSTR, this, pauseScrollFunc);
			ivy.UIManager.getInstance().registerUIRefreshFunctionWithName(ivy.UIListView.UIListViewResumeScrollEventSTR, this, function() {
				if (this._listView) {
					this._listView.setEnabled(true);
				}
			}.bind(this));
			if (ivy.TeachManager.getInstance().isTeaching()) {
				pauseScrollFunc();
			}
		}
		this.setUIElementName(formName, blockName);
		this.setAnchorType(anchorType);
		this.scheduleUpdate();
	},

	forceDoLayout : function() {
		if (this._listView)
			this._listView.forceDoLayout();
	},

	setBounceEnabled : function(enable) {
		if (this._listView)
			this._listView.setBounceEnabled(enable);
	},
	getItemMargin : function() {
		if (this._listView)
			return this._listView.getItemsMargin();
		return 0;
	},
	setItemMargin : function(margin) {
		if (this._listView)
			this._listView.setItemsMargin(margin);
	},
	setClippingType : function(ct) {
		if (this._listView)
			this._listView.setClippingType(ct);
	},
	removeCustomItem : function(index) {
		if (this._listView)
			this._listView.removeItem(index);
	},
	jumpToPercent : function(percent) {
		if (this._listView) {
			switch (this._listView.getDirection()) {
				case ccui.ScrollView.DIR_VERTICAL:
					this._listView.jumpToPercentVertical(percent);
					break;
				case ccui.ScrollView.DIR_HORIZONTAL:
					this._listView.jumpToPercentHorizontal(percent);
					break;
				default:
					break;
			}
		}
	},
	jumpToItem : function(index, positionRatioInView=cc.p(0.5, 0.5), itemAnchorPoint=cc.p(0.5, 0.5)) {
		if (this._listView)
			this._listView.jumpToItem(index, positionRatioInView, itemAnchorPoint);
	},
	scrollToPercent : function(percent,time,attenuated) {
		if (this._listView) {
			switch (this._listView.getDirection()) {
				case ccui.ScrollView.DIR_VERTICAL:
					this._listView.scrollToPercentVertical(percent, time, attenuated);
					break;
				case ccui.ScrollView.DIR_HORIZONTAL:
					this._listView.scrollToPercentHorizontal(percent, time, attenuated);
					break;
				default:
					break;
			}
		}
	},
	scrollToItem : function(index, timeInSec=1.0, positionRatioInView=cc.p(0.5,0.5), itemAnchorPoint=cc.p(0.5, 0.5)) {
		if (this._listView) {
			this._listView.scrollToItem(index,positionRatioInView, itemAnchorPoint, timeInSec);
		}
	},
	getCurrentScrollPercent : function() {
		let percent = 0;
		if (this._listView) {
			switch (this._listView.getDirection()) {
				case ccui.ScrollView.DIR_VERTICAL: {
					let inner = this._listView.getInnerContainer();
					let viewHeight = this._listView.getContentSize().height;
					let height = inner.getContentSize().height;
					let maxHeight = height - viewHeight;
					let y = inner.getPosition().y+ maxHeight;
					let percent = y*100.0 / maxHeight;
					break;
				}
				case ccui.ScrollView.DIR_HORIZONTAL: {
					let inner = this._listView.getInnerContainer();
					let viewWidth = this._listView.getContentSize().width;
					let width = inner.getContentSize().width;
					let maxWidth = width - viewWidth;
					let x = inner.getPosition().x + maxWidth;
					let percent = x*100.0 / maxWidth;
					break;
				}
				default:
					break;
			}
		}
		if (percent > 100)
			percent = 100;
		if (percent < 0)
			percent = 0;
		return percent;
	},
	/**
	 * void insertCustomItem(cc::UIBase* item,int32_t idx);
	 * void insertCustomItem(cocos2d::Node* node,int32_t idx);
	 * */
	insertCustomItem : function(node, idx) {
		if (!this._listView) {
			return;
		}
		let default_item = new ccui.Layout();
		default_item.setCascadeColorEnabled(true);
		default_item.setCascadeOpacityEnabled(true);
		default_item.setTouchEnabled(true);
		default_item.setContentSize(node.getContentSize());
		default_item.addChild(node);
		if (node instanceof ivy.UIBase) {
			node.setPosition(cc.p(default_item.getContentSize().width / 2.0, default_item.getContentSize().height / 2.0));
		}
		this._listView.insertCustomItem(default_item, idx);
		this._layoutChildsVec.splice(idx, 0, default_item);//insert
	},
	/**
	 * void pushBackCustomItem(cc::UIBase* item);
	 * void pushBackCustomItem(cocos2d::Node* node);
	 * */
	pushBackCustomItem : function(node) {
		if (!this._listView) {
			return;
		}
		if (node instanceof ivy.UIBase) {
			let default_item = new ccui.Layout();
			default_item.setCascadeColorEnabled(true);
			default_item.setCascadeOpacityEnabled(true);
			default_item.setTouchEnabled(true);
			default_item.setContentSize(node.getContentSize());
			default_item.addChild(node);
			switch (node.getAnchorType()) {
				case ivy.UIBase.UIAnchorType.eAnchorHV:
					node.setPosition(cc.p(default_item.getContentSize().width / 2.0, default_item.getContentSize().height / 2.0));
					break;
				case ivy.UIBase.UIAnchorType.eAnchorLT:
					node.setPosition(cc.p(0, default_item.getContentSize().height));
					break;
				case ivy.UIBase.UIAnchorType.eAnchorLB:
					node.setPosition(cc.p(0, 0));
					break;
				case ivy.UIBase.UIAnchorType.eAnchorRT:
					node.setPosition(cc.p(default_item.getContentSize().width, default_item.getContentSize().height));
					break;
				case ivy.UIBase.UIAnchorType.eAnchorRB:
					node.setPosition(cc.p(default_item.getContentSize().width, 0));
					break;
				case ivy.UIBase.UIAnchorType.eAnchorHT:
					node.setPosition(cc.p(default_item.getContentSize().width / 2.0, default_item.getContentSize().height));
					break;
				case ivy.UIBase.UIAnchorType.eANchorHB:
					node.setPosition(cc.p(default_item.getContentSize().width / 2.0, 0));
					break;
				case ivy.UIBase.UIAnchorType.eAnchorLV:
					node.setPosition(cc.p(0, default_item.getContentSize().height / 2.0));
					break;
				case ivy.UIBase.UIAnchorType.eAnchorRV:
					node.setPosition(cc.p(default_item.getContentSize().width, default_item.getContentSize().height / 2.0));
					break;
				default:
					break;
			}

			this._listView.pushBackCustomItem(default_item);
			this._layoutChildsVec.push(default_item);
			node.setSrcPosition(node.getPosition());
		} else {
			let default_item = new ccui.Layout();
			default_item.setCascadeColorEnabled(true);
			default_item.setCascadeOpacityEnabled(true);
			default_item.setTouchEnabled(true);
			default_item.setContentSize(node.getContentSize());
			default_item.addChild(node);
			this._listView.pushBackCustomItem(default_item);
			this._layoutChildsVec.push(default_item);
		}
	},
	getInnerContainer : function() {
		if (this._listView) {
			return this._listView.getInnerContainer();
		}
		return null;
	},
	setAnchorType : function(type) {
		this._super(type);
		let rect = this.getSrcRect();
		let size = cc.size(rect);
		this.setContentSize(size);
		if (this._listView) {
			this._listView.setPosition(cc.p(-size.width / 2.0, -size.height / 2.0));
			this.setPosition(ivy.Tools.ConvertPointToGL(cc.p(rect.x + size.width / 2.0, rect.y + size.height / 2.0)));
			this.setSrcPosition(this.getPosition());
		}
	},
	addEventListener : function(callback) {
		if (this._listView) {
			this._listView.addEventListener(callback);
		}
	},
	removeAllItems : function() {
		if (this._listView)
			this._listView.removeAllItems();
		this._layoutChildsVec = [];
		this._lazyLoadVec.clear();
	},
	getItemsCount : function() {
		if (this._listView)
			return this._listView.getChildrenCount();
		return 0;
	},
	getBaseListView : function() {
		return this._listView;
	},
	onChildCreateComplete : function() {
		let children = this.getChildren();
		let needReAddUIBaseControlsVec = [];//std::vector<UIBase*>
		for (let child of children) {
			if (child instanceof ivy.UIBase) {
				needReAddUIBaseControlsVec.push(child);
			}
		}

		for (let itr of needReAddUIBaseControlsVec) {
			itr.removeFromParent();
			this.addToChildrenList(itr);
			this.pushBackCustomItem(itr);
		}

		if (this._listView)
			this._listView.doLayout();
	},
	doSetAllChildDetectVisble : function() {
		let index = 0;
		let listViewContentSize = this.getContentSize();
		let innerContentSize = this.getInnerContainer().getContentSize();

		if (this._listView.getDirection() === ccui.ScrollView.DIR_VERTICAL) {
			let allHeight = 0;
			let marginHeight = this._listView.getItemsMargin();
			for (let child of this._layoutChildsVec) {
				if (child.getParent()) {
					let childContentSize = child.getContentSize();
					let startX = listViewContentSize.height - innerContentSize.height + allHeight + childContentSize.height;
					let endX = startX - listViewContentSize.height - childContentSize.height;
					child.unschedule("__check__");
					child.schedule(function() {
						let node = child.getParent();
						if (node.getPosition().y <= startX && node.getPosition().y >= endX) {
							child.setVisible(true);
						} else {
							child.setVisible(false);
						}
					}, 0, cc.REPEAT_FOREVER, 0, "__check__");
					allHeight += childContentSize.height + marginHeight;
					++index;
				}
			}
		} else {
			let allWidth = 0;
			let marginWidth = this._listView.getItemsMargin();
			for (let child of this._layoutChildsVec) {
				if (child.getParent()) {
					let childContentSize = child.getContentSize();
					let startX = allWidth - childContentSize.width;
					let endX = startX + listViewContentSize.width + childContentSize.width;
					child.unschedule("__check__");
					child.schedule(function() {
						let node = child.getParent();
						if (node.getPosition().y <= startX && node.getPosition().y >= endX) {
							child.setVisible(true);
						} else {
							child.setVisible(false);
						}
					}, 0, cc.REPEAT_FOREVER, 0, "__check__");
					//可能需要处理margin值
					allWidth += childContentSize.width;
					++index;
				}
			}
		}
	},

	update : function(dt) {
		let count = 0;
		while(!this._lazyLoadVec.empty()) {
			if (count >= this._times)
				return;
			let func = this._lazyLoadVec.front();
			func();
			this._lazyLoadVec.pop_front();
			++count;
		}
		this._isUpdating = false;
		this.unscheduleUpdate();
		if (this._loadCompleteCallback)
			this._loadCompleteCallback();
	},
	pushLazyLoadFunc : function(func) {
		this._lazyLoadVec.push_back(func);
		if (!this._isUpdating) {
			this.scheduleUpdate();
			this._isUpdating = true;
		}
	},
	onExit : function() {
		this.unscheduleUpdate();
		this._lazyLoadVec.clear();
		this._super();
	},
	isLoadingAllItemComplete : function() {
		return this._lazyLoadVec.empty();
	},
	registerCompleteCallback : function(callback) {
		if (callback) {
			this._loadCompleteCallback = callback;
		}
	},
	////////////////////////////////////////////////////////////////////////////////////////////////////////////////////protected:
	_listView : null,//cocos2d::ui::ListView*
	_layoutChildsVec : null,//std::vector<cocos2d::ui::Layout *>
	_lazyLoadVec : null,//std::deque<std::function<void()>>
	_times : 4,
	_isUpdating : false,
	_loadCompleteCallback : null,//std::function<void(void)>
});

ivy.UIListView.create = function(formName, blockName, sourceControlData) {
	return new ivy.UIListView(formName, blockName, sourceControlData);
};

ivy.UIListView.UIListViewPauseScrollEventSTR = "_UIListViewPauseScrollEvent_";
ivy.UIListView.UIListViewResumeScrollEventSTR = "_UIListViewResumeScrollEvent_";
